// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.options

import com.intellij.openapi.Disposable
import com.intellij.openapi.ui.DialogPanel
import com.intellij.openapi.util.ClearableLazyValue
import com.intellij.openapi.util.Disposer
import org.jetbrains.annotations.Nls
import org.jetbrains.annotations.NonNls
import javax.swing.JComponent

/**
 * @author yole
 */
abstract class BoundConfigurable(
  @Nls private val displayName: String,
  @NonNls private val helpTopic: String? = null
) : DslConfigurableBase(), Configurable {
  override fun getDisplayName(): String = displayName
  override fun getHelpTopic(): String? = helpTopic
}

abstract class DslConfigurableBase : UnnamedConfigurable {
  protected var disposable: Disposable? = null
    private set

  private val panel = object : ClearableLazyValue<DialogPanel>() {
    override fun compute(): DialogPanel {
      if (disposable == null) {
        disposable = Disposer.newDisposable()
      }
      val panel = createPanel()
      panel.registerValidators(disposable!!)
      return panel
    }
  }

  abstract fun createPanel(): DialogPanel

  final override fun createComponent(): JComponent? = panel.value

  override fun isModified() = panel.value.isModified()

  override fun reset() {
    panel.value.reset()
  }

  override fun apply() {
    panel.value.apply()
  }

  override fun disposeUIResources() {
    disposable?.let {
      Disposer.dispose(it)
      disposable = null
    }

    panel.drop()
  }
}

abstract class BoundSearchableConfigurable(displayName: String, helpTopic: String, private val _id: String = helpTopic)
  : BoundConfigurable(displayName, helpTopic), SearchableConfigurable {
  override fun getId(): String = _id
}
